/*
 * LightShadowMap.cpp
 *
 *  Created on: 10-07-2013
 *      Author: Jarek
 */

#include "LightShadowMap.h"

LightShadowMap::LightShadowMap(char* VSPath, char* FSPath)
{
	createShader(VSPath, FSPath);
	createProgram();

	uniforms.modelViewProjectionMatrix 		= glGetUniformLocation(programHandler, "modelViewProjMatrix");

	attributes.position						= glGetAttribLocation(programHandler, "position");

	if (uniforms.modelViewProjectionMatrix < 0)
		LOGE("LightShadowMap Shader: couldn't find uniform \"modelViewProjMatrix\".");

	if (attributes.position	< 0)
		LOGE("LightShadowMap Shader: couldn't find attribute \"position\".");
}

LightShadowMap::~LightShadowMap() {
	// TODO Auto-generated destructor stub
}

void LightShadowMap::useAttributes(bool isAttributes)
{
	if( isAttributes)
	{
		glEnableVertexAttribArray(attributes.position);
	}
	else
	{
		glDisableVertexAttribArray(attributes.position);
	}
}

void LightShadowMap::useShaderOnMesh(const Mesh& mesh)
{
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.facesBuffer);

	if(attributes.position >= 0 && mesh.facesBuffer)
	{
		glBindBuffer(GL_ARRAY_BUFFER, mesh.verticesBuffer);
		glEnableVertexAttribArray(attributes.position);
		glVertexAttribPointer(attributes.position, 3, GL_FLOAT, GL_FALSE, 0, 0);
	}
}

void LightShadowMap::draw(const ETime& time, const World& world, Light& light)
{
	this->useProgram();
	this->drawN(time, *world.root, light);
}

void LightShadowMap::drawN(const ETime& time, Node& node, Light& light)
{
	if(node.nodeType == Node::NODE_TYPE_MODEL)
	{
		Model& model = *reinterpret_cast<Model*>(&node);
		setUniformMatrix4x4f(uniforms.modelViewProjectionMatrix, &light.getModelViewProjectionMatrix(time, model.getWorldMatrix(time)).at(0, 0));
		for(uint i = 0; i< model.meshesCount; i++)
		{
			this->useShaderOnMesh(*model.meshes[i]);
			glDrawElements(GL_TRIANGLES, model.meshes[i]->facesCount * 3, GL_UNSIGNED_INT, 0);
		}
	}

	for(uint j = 0; j < node.childrenCount; j++)
	{
		drawN(time, *node.children[j], light);
	}
}

